/*
 * Residue.h
 *
 *  Created on: Jul 6, 2013
 *      Author: x
 */

#ifndef RESIDUE_H_
#define RESIDUE_H_

#include <vector>
#include <string>

namespace mcce {
class Conformer;
class Protein;

class Residue {
private:
	bool Fixed;
	Protein *inProt;    // a pointer to go back to protein object

	size_t onFreeConf;  // index of free conformer which is actually on.

	std::string resName;       // e.g. resName = "ASPA0085"
	std::vector<Conformer> conformers;


	std::vector<Residue *> neighborRes;
	std::vector<Residue *> freeNeighborRes;

	// only contain free conformers in the residue.
	std::vector<std::vector<Conformer*> > groupedFreeConf;
	std::vector<Conformer*> freeConformers;

public:
	Residue();
	Residue(const Conformer &conf);
	virtual ~Residue();

	Residue& addConformer(const Conformer &conf);

	std::string getResName() const {
		return resName;
	}

	std::vector<Residue *>& getNeighborRes() {
		return neighborRes;
	}

	Residue& addNeighborRes(Residue *res) {
		neighborRes.push_back(res);
		return *this;
	}

	void setNeighborRes(float threshold);

	void setFreeNeighborRes();


	std::vector<Residue *>& getFreeNeighborRes() {
		return freeNeighborRes;
	}

	void setInProt(Protein *prot) {
		inProt = prot;
	}

	Protein* getInProt() {
		return inProt;
	}

	void setOnFreeConf(int onConf) {
		onFreeConf = onConf;
	}

	size_t getOnFreeConf() {
		return onFreeConf;
	}

	bool isResNeighbor(Residue &res, float threshold=0.1);

	void setFreeConformers();

	std::vector<Conformer*>& getFreeConformers() {
		return freeConformers;
	}

	void adjustHead3Flag();

	void setGroupedFreeConf();

	// randomly pick a different type of conformer in this residue for MC sample
	Conformer* nextDiffConf(Conformer *conf);

	std::vector<std::vector<Conformer*> >& getGroupedFreeConf() {
		return groupedFreeConf;
	}

	void setResName(std::string &resName) {
		this->resName = resName;
	}

	std::vector<Conformer>& getConformers() {
		return conformers;
	}

	void setConformers(const std::vector<Conformer>& conformers) {
		this->conformers = conformers;
	}

	bool isFixed() const {
		return Fixed;
	}

	void setFixed(bool isFixed) {
		this->Fixed = isFixed;
	}
};

} /* namespace mcce */
#endif /* RESIDUE_H_ */
